今天來跟大家介紹詳細解釋如何利用 terraform 實作具有 CICD 的 cloud run + cloud sql
從根目錄開始看, 可以得知整個專案很清楚的拆分成服務實體
和 CICD
兩個元件, 按照順序建置
module "sql-instance" {
source = "./instances"
service_name = module.global_var.service-name
region = module.global_var.region
run-sa = "77786086397-compute@developer.gserviceaccount.com"
db-name = "postgres"
}
module "cicd" {
source = "./cicd"
depends_on = [module.sql-instance]
git_token = "<your git token>"
build_sa = "service-77786086397@gcp-sa-cloudbuild.iam.gserviceaccount.com"
git_app_id = "36856157"
builder_sa = "77786086397@cloudbuild.gserviceaccount.com"
service_name = module.global_var.service-name
}
服務實體是按照順序建置 cloud sql, sql user, cloud run
此時有一個小細節, 因為真正的 image 可以靠 CD 推上來, 所以這裡可以直接引用一個你所需要的靜態頁面的圖像, 之後網站維護也直接用這個圖像即可, 很方便
resource "google_sql_database_instance" "instance" {
name = "${var.service_name}-sql"
region = var.region
database_version = "POSTGRES_15"
settings {
tier = "db-f1-micro"
disk_type = "PD_HDD"
disk_size = 10
database_flags {
name = "cloudsql.iam_authentication"
value = "on"
}
}
deletion_protection = "false"
}
resource "time_sleep" "wait_seconds" {
depends_on = [google_sql_database_instance.instance]
create_duration = "60s"
}
resource "google_sql_user" "iam_service_account_user" {
# Note: for Postgres only, GCP requires omitting the ".gserviceaccount.com" suffix
# from the service account email due to length limits on database usernames.
name = trimsuffix(var.run-sa, ".gserviceaccount.com")
/* name = var.run-sa */
instance = google_sql_database_instance.instance.name
type = "CLOUD_IAM_SERVICE_ACCOUNT"
depends_on = [time_sleep.wait_seconds]
}
resource "google_cloud_run_v2_service" "default" {
name = var.service_name
location = var.region
ingress = "INGRESS_TRAFFIC_ALL"
template {
service_account = var.run-sa
scaling {
max_instance_count = 3
min_instance_count = 0
}
volumes {
name = "cloudsql"
cloud_sql_instance {
instances = [google_sql_database_instance.instance.connection_name]
}
}
containers {
image = "us-docker.pkg.dev/cloudrun/container/hello"
env {
name = "DB_IAM_USER"
value = google_sql_user.iam_service_account_user.name
}
env {
name = "DB_NAME"
value = var.db-name
}
env {
name = "INSTANCE_CONNECTION_NAME"
value = google_sql_database_instance.instance.connection_name
}
volume_mounts {
name = "cloudsql"
mount_path = "/cloudsql"
}
}
}
traffic {
type = "TRAFFIC_TARGET_ALLOCATION_TYPE_LATEST"
percent = 100
}
depends_on = [google_sql_user.iam_service_account_user]
}
CICD 組件相對複雜, 不過我們前面的文章都大概聊過了
依序執行
module "git-connection" {
source = "./github-connection"
secret_id = "github-token"
name = "github-connection"
git_token = var.git_token
git_app_id = var.git_app_id
build_sa = var.build_sa
region = module.global_var.region
git-url = module.global_var.git-url
}
resource "google_artifact_registry_repository" "docker-images" {
location = module.global_var.region
repository_id = var.service_name
description = "example docker repository"
format = "DOCKER"
docker_config {
immutable_tags = false
}
}
resource "google_project_iam_member" "r1" {
project = module.global_var.project_id
role = "roles/run.admin"
member = "serviceAccount:${var.builder_sa}"
}
resource "google_project_iam_member" "r2" {
project = module.global_var.project_id
role = "roles/iam.serviceAccountUser"
member = "serviceAccount:${var.builder_sa}"
depends_on = [google_project_iam_member.r1]
}
module "build" {
source = "./cloud-build"
name = var.service_name
file = module.global_var.build-file-path
region = module.global_var.region
repo-id = module.git-connection.repo-id
repo-name = google_artifact_registry_repository.docker-images.name
depends_on = [module.git-connection, google_artifact_registry_repository.docker-images, google_project_iam_member.r2]
}